﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Data;
using System.IO;
using System.Drawing;
using System.Text.RegularExpressions;
using System.Diagnostics;

namespace AutoParkingManagement
{
    public abstract class Common
    {        
        public enum SYSTEM_PERMISSIONS
        {
            NONE =-1,
            VEHICLE_KEEPER=0,
            ACCOUNTANT=1,
            MANAGER=2,
            ADMIN=3,
            SUPER_ADMIN=4
        }

        public static bool IsEmail(string inputEmail)
        {
            if (String.IsNullOrEmpty(inputEmail)) return true;
            string strRegex = @"^([a-zA-Z0-9_\-\.]+)@((\[[0-9]{1,3}" +
                  @"\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\" +
                  @".)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$";
            Regex re = new Regex(strRegex);
            return re.IsMatch(inputEmail);
        }

        public static object DBNullValue(object value)
        {
            if (value == null || String.IsNullOrEmpty(value.ToString()))
            {
                return DBNull.Value;
            }
            return value;
        }

        /// <summary>
        /// Check if a form has been loaded
        /// </summary>
        /// <param name="TypeOfForm">type of form</param>
        /// <returns>true/false</returns>
        public static bool FormExisted(Type TypeOfForm)
        {
            foreach (Form frm in Application.OpenForms)
            {
                if (frm.GetType() == TypeOfForm)
                {
                    if (frm.WindowState == FormWindowState.Minimized)
                    {
                        frm.WindowState = FormWindowState.Normal;
                    }
                    frm.Activate();
                    return true;
                }
            }
            return false;
        }

        #region Image
        /// <summary>
        /// Get image before execute stored procedure
        /// </summary>
        /// <param name="image">Image</param>
        /// <returns>return object</returns>
        public static object DBNullImage(object image)
        {
            if (image == null || image.ToString() == String.Empty)
            {
                return System.Data.SqlTypes.SqlBinary.Null;
            }
            return image;
        }

        /// <summary>
        /// Get content of image from picture box
        /// </summary>
        /// <returns>array of bytes</returns>
        public static byte[] GetImageContent(PictureBox picbImage)
        {
            if (picbImage == null)
            {
                return null;
            }
            ///////////////////////////////////////////
            Image img = picbImage.Image;
            if (img == null)
            {
                return null;
            }
            else
            {
                MemoryStream stream = new MemoryStream();
                img.Save(stream, img.RawFormat);
                return stream.GetBuffer();
            }
        }

        public static byte[] ImageToByteArray(System.Drawing.Image image)
        {
            if (image == null) return null;
            MemoryStream ms = new MemoryStream();
            image.Save(ms, System.Drawing.Imaging.ImageFormat.Gif);
            return ms.ToArray();
        }

        public static Image ByteArrayToImage(byte[] byteArrayIn)
        {
            MemoryStream ms = new MemoryStream(byteArrayIn);
            Image returnImage = Image.FromStream(ms);
            return returnImage;
        }

        /// <summary>
        /// Save image to plate number folder
        /// </summary>
        /// <param name="img">image</param>
        /// <returns>image path (err: return empty)</returns>
        public static string SaveImage(Image img)
        {
            string strDir = String.Format(@"{0}\PlateNumber", Application.StartupPath);
            if (!Directory.Exists(strDir))
            {
                Directory.CreateDirectory(strDir);
            }
            else
            {
                string[] files = Directory.GetFiles(strDir);
                foreach (string sFile in files)
                {
                    try
                    {
                        File.Delete(sFile);
                    }
                    catch
                    {
                    }
                }
            }

            if (img == null) return String.Empty;

            string imageFile= String.Format(@"{0}\{1}.jpg", strDir, Guid.NewGuid());
            try
            {
                img.Save(imageFile, System.Drawing.Imaging.ImageFormat.Jpeg);
            }
            catch
            {
                return String.Empty;
            }
            if (File.Exists(imageFile)) return imageFile;
            return String.Empty;
        }

        #endregion


        #region Profiles
        private static string xmlProfile = String.Format(@"{0}\Profile.xml", Application.StartupPath);
        private static void CreateProfile()
        {
            try
            {
                if (File.Exists(xmlProfile)) return;
                DataTable dt = new DataTable("Profile");
                dt.Columns.Add("Username", typeof(string));
                dt.Columns.Add("LeftEntry", typeof(bool));
                dt.Columns.Add("RightEntry", typeof(bool));
                DataRow row = dt.NewRow();
                row[0] = Guid.NewGuid().ToString();
                row[1] = true;
                row[2] = true;
                dt.Rows.Add(row);
                dt.WriteXml(xmlProfile);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        /// <summary>
        /// Write profile for left & right lane
        /// </summary>
        /// <param name="username">username</param>
        /// <param name="leftEntry">Left lane (True: Entry, False: Exit)</param>
        /// <param name="rightEntry">Right lane (True: Entry, False: Exit)</param>
        public static void WriteProfile(string username, bool leftEntry, bool rightEntry)
        {
            try
            {
                CreateProfile();
                DataSet ds = new DataSet();
                ds.ReadXml(xmlProfile);
                ////////////////////////
                string strSelect = String.Format("Username='{0}'", username);
                DataRow[] rows = ds.Tables[0].Select(strSelect);
                if (rows.Length == 0)
                {
                    DataRow newRow = ds.Tables[0].NewRow();
                    newRow["Username"] = username;
                    newRow["LeftEntry"] = leftEntry;
                    newRow["RightEntry"] = rightEntry;
                    ds.Tables[0].Rows.Add(newRow);
                }
                else
                {
                    rows[0]["LeftEntry"] = leftEntry;
                    rows[0]["RightEntry"] = rightEntry;
                }
                ds.Tables[0].WriteXml(xmlProfile);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public static DataRow ReadProfile(string username)
        {
            try
            {
                if (!File.Exists(xmlProfile)) return null;
                DataSet ds = new DataSet();
                ds.ReadXml(xmlProfile);
                string strSelect = String.Format("Username='{0}'", username);
                DataRow[] rows = ds.Tables[0].Copy().Select(strSelect);
                if (rows.Length == 0) return null;
                return rows[0];
            }
            catch (Exception ex)
            {
                return null;
            }
        }

        public static Image ResizeImage(Image imgToResize, int width, int height)
        {
            Bitmap bitmap = new Bitmap(width, height);
            Graphics graphic = Graphics.FromImage((Image)bitmap);
            graphic.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;

            graphic.DrawImage(imgToResize, 0, 0, width, height);
            graphic.Dispose();

            return (Image)bitmap;
        }

        #endregion

        #region Datasource for combobox
        /// <summary>
        /// Card status
        /// </summary>
        public static IList<String> CardStatus
        {
            get
            {
                IList<String> list = new List<String>();
                list.Add("Tất cả");
                list.Add("Vô hiệu");
                list.Add("Kích hoạt");
                return list;
            }
        }

        /// <summary>
        /// Datasource cardtypes
        /// </summary>
        /// <param name="displayEmpty">true: first element is emty</param>
        /// <returns></returns>
        public static DataTable GetCardTypes(bool displayEmpty)
        {
            string strCommandText = "SELECT CardTypeID, [Name] FROM CardType ORDER BY [Name]";
            DataTable dt = SqlHelper.ExecuteDataTable(CommandType.Text, strCommandText, null);
            if (displayEmpty)
            {
                DataRow firstRow = dt.NewRow();
                firstRow["CardTypeID"] = DBNull.Value;
                firstRow["Name"] = "Tất cả";
                dt.Rows.InsertAt(firstRow, 0);
            }            
            return dt;
        }

        public static DataTable GetCardReaderRFID()
        {
            DataTable dt = new DataTable();
            dt.Columns.Add("ID", typeof(Int32));
            dt.Columns.Add("Value", typeof(String));
            DataRow dr0 = dt.NewRow();
            dr0["ID"] = 0;
            dr0["Value"] = "Không có";
            dt.Rows.Add(dr0);
            DataRow dr1 = dt.NewRow();
            dr1["ID"] = AppConfig.RFIDLEFT;
            dr1["Value"] = "Bên trái";
            dt.Rows.Add(dr1);
            DataRow dr2 = dt.NewRow();
            dr2["ID"] = AppConfig.RFIDRIGHT;
            dr2["Value"] = "Bên phải";
            dt.Rows.Add(dr2);
            return dt;
        }

        public static DataTable GetCustomerTypes(bool displayEmpty)
        {
            string strCommandText = "SELECT CustomerTypeID, [Name] FROM CustomerType ORDER BY [Name]";
            DataTable dt = SqlHelper.ExecuteDataTable(CommandType.Text, strCommandText, null);
            if (displayEmpty)
            {
                DataRow firstRow = dt.NewRow();
                firstRow["CustomerTypeID"] = DBNull.Value;
                firstRow["Name"] = "Tất cả";
                dt.Rows.InsertAt(firstRow, 0);
            }
            return dt;
        }
        #endregion


        /// <summary>
        /// Get system time
        /// </summary>
        /// <returns></returns>
        public static DateTime GetSystemDBTime()
        {
            StringBuilder sb = new StringBuilder();
            sb.Append("SELECT GetDate() AS DbTime");

            object obj = SqlHelper.ExecuteScalar(CommandType.Text, sb.ToString(), null);
            return (DateTime)obj;
        }        

        /// <summary>
        /// Encrypt string by md5 method
        /// </summary>
        /// <param name="sPassword"></param>
        /// <returns></returns>
        public static string Md5Encrypt(string strTemp)
        {
            System.Security.Cryptography.MD5CryptoServiceProvider x = new System.Security.Cryptography.MD5CryptoServiceProvider();
            byte[] bs = System.Text.Encoding.UTF8.GetBytes(strTemp);
            bs = x.ComputeHash(bs);
            System.Text.StringBuilder s = new System.Text.StringBuilder();
            foreach (byte b in bs)
            {
                s.Append(b.ToString("x2").ToLower());
            }
            return s.ToString();
        }

        public static void ShowMessage(string text, string message)
        {            
            MyMessageBox msgBox = new MyMessageBox(text, message);
            msgBox.ShowDialog();
            msgBox.Dispose();
            msgBox = null;
            GC.Collect();
        }

        private static string GetOnlyNumberAndAlphabet(string source)
        {
            foreach (char c in source.ToCharArray())
            {
                if (!Regex.IsMatch(c.ToString(), @"^[a-zA-Z0-9]+$"))
                {
                    source = source.Replace(c.ToString(), String.Empty);
                }
            }
            return source;
        }

        /// <summary>
        /// Compare 2 plates
        /// </summary>
        /// <param name="plateNo1"></param>
        /// <param name="plateNo2"></param>
        /// <returns></returns>
        public static bool ComparePlateNumber(string plateNo1, string plateNo2)
        {
            plateNo1 = GetOnlyNumberAndAlphabet(plateNo1);
            plateNo2 = GetOnlyNumberAndAlphabet(plateNo2);
            return (plateNo1.ToUpper().Equals(plateNo2.ToUpper()));
        }

        
        public static void ExecuteCommandSync(string IpServer)
        {
            try
            {
                string command = String.Format(@"net time \\{0} /set /Y",IpServer);
                // create the ProcessStartInfo using "cmd" as the program to be run,
                // and "/c " as the parameters.
                // Incidentally, /c tells cmd that we want it to execute the command that follows,
                // and then exit.
                System.Diagnostics.ProcessStartInfo procStartInfo =
                    new System.Diagnostics.ProcessStartInfo("cmd", "/c " + command);

                // The following commands are needed to redirect the standard output.
                // This means that it will be redirected to the Process.StandardOutput StreamReader.
                procStartInfo.RedirectStandardOutput = true;
                procStartInfo.UseShellExecute = false;
                // Do not create the black window.
                procStartInfo.CreateNoWindow = true;
                // Now we create a process, assign its ProcessStartInfo and start it
                System.Diagnostics.Process proc = new System.Diagnostics.Process();
                proc.StartInfo = procStartInfo;
                proc.Start();
                proc.WaitForExit();

            }
            catch
            {
                // Log the exception
            }
        }
    }
}
